import axios from "axios";
import router from "@/router";
import _ from "lodash";

// const PREFIX = '/v2'
const IGNORE_TOKEN_URLS = new Set();
IGNORE_TOKEN_URLS.add("/auth/oauth/token");
IGNORE_TOKEN_URLS.add("/area/tree");

function isIgnoreTokenUrl (url) {
  return IGNORE_TOKEN_URLS.has(url);
}

const HTTP_ERRORS = {
  400: "参数错误",
  401: "请重新登录",
  403: "拒绝访问",
  404: "资源不存在",
  500: "内部错误",
  501: "不支持的方法",
  502: "网关错误",
  504: "网关超时"
};

const SKIP_CODES = [-10341, 10010, 10205, 1200, 12531, 173009, 157002, -10348, 20501, 13001, 13000];

function isSuccessCode ({ data }) {
  if (data?.code === 157002) {
    router.push("/errorView");
  }
  return data?.code === 0 || !data?.code || SKIP_CODES.includes(data?.code);
}

const resolveTokenError = _.debounce((Vue, config) => {
  if (isIgnoreTokenUrl(config.url)) {
    return;
  }

  Vue.prototype.$message({
    message: "登录已失效",
    type: "error"
  });
  const timer = setTimeout(() => {
    clearTimeout(timer);
    Vue.prototype.writeStorage("REDIRECT_URL", window.location.href);
    window.location.href = "/login";
  }, 500);
}, 200);

function resolveAccessToken (config) {
  let token = sessionStorage.getItem("token");
  if (token) {
    config.headers["Authorization"] = "Bearer " + token;
  }
}

const resolveTimestamp = (config) => {
  if (config.method === "get") {
    // 添加时间戳参数，防止浏览器（IE）对get请求的缓存
    config.params = {
      ...config.params,
      t: new Date().getTime()
    };
  }
};

function configureRequest () {
  axios.interceptors.request.use(
    (config) => {
      config.headers["Content-Type"] = "application/json;charset=UTF-8";
      config.headers["Access-Control-Allow-Origin"] = "*";
      config.headers["Access-Control-Allow-Header"] = "Content-Type,*";
      // resolveAdminUrl(config);
      resolveAccessToken(config);
      resolveTimestamp(config);
      return config;
    },
    (error) => {
      return Promise.reject(error.response);
    }
  );
}

function configureResponse (Vue) {
  axios.interceptors.response.use(
    (response) => {
      const { data, config } = response;
      if (401 === data?.code) {
        resolveTokenError(Vue, config);
        return data;
      }

      if (isSuccessCode(response)) {
        return data;
      }

      Vue.prototype.$message({
        message: data?.message || '服务端异常',
        type: "error"
      });
      return Promise.reject(data);
    },
    (error) => {
      if (error.response) {
        // 根据请求失败的http状态码去给用户相应的提示
        let message =
          HTTP_ERRORS[error.response?.status] || error.response?.data?.message;
        Vue.prototype.$message({
          message,
          type: "error"
        });
        return Promise.reject(error);
      }
    }
  );
}

// axios默认配置
axios.defaults.timeout = 10000; // 超时时间
axios.defaults.baseURL = process.env.VUE_APP_URL;

export default {
  install (Vue) {
    configureRequest(Vue);
    configureResponse(Vue);
  }
};
